package com.leyou.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.config.OSSProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.*;

/**
 * @author: guojy
 * @date: 2020/3/2 16:00
 * @Description:
 * @version: 1.0
 */
@Service
public class UploadService {
    private static final List<String> iamgeSuffix = Arrays.asList("image/jpg", "image/png", "image/jpeg", "image/bmp");

    public String uploadImage(MultipartFile file) {
//        long size = file.getSize();
//        System.out.println(size);
//        if (size > (1 * 1024 * 1024)) {
//            throw new LyException(ExceptionEnum.EXCEEDED_MAXIMUM_LIMIT);
//        }
        // 1、验证图片格式
        String type = file.getContentType();
        if (!iamgeSuffix.contains(type)) {
            throw new LyException(ExceptionEnum.INVALID_FILE_TYPE);
        }
        // 2、验证文件内容是否是 图片
        InputStream inputStream = null;
        BufferedImage read = null;
        try {
            inputStream = file.getInputStream();
            read = ImageIO.read(inputStream);
        } catch (IOException e) {
            // 捕获异常，文件读写失败
            throw new LyException(ExceptionEnum.FILE_WRITER_ERROR);
        }
        if (read == null) {
            throw new LyException(ExceptionEnum.INVALID_FILE_TYPE);
        }
        // 3、保存图片,将图片放在nginx服务器中，
        File dir = new File("D:\\Develop\\nginx-1.12.2\\nginx-1.12.2\\html");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        try {
            file.transferTo(new File(dir, file.getOriginalFilename()));
            // 拼接图片地址
            return "http://image.leyou.com/" + file.getOriginalFilename();
        } catch (IOException e) {
            throw new LyException(ExceptionEnum.FILE_UPLOAD_ERROR);
        }
    }

    @Autowired
    private OSSProperties prop;
    @Autowired
    private OSS client;

    /**
     * 获取签名的 方法，官网
     *
     * @return
     */
    public Map<String, Object> getsignature() {

        // 以下通过读取配置文件的方式
        String accessId = prop.getAccessKeyId(); // 请填写您的AccessKeyId。
        String accessKey = prop.getAccessKeySecret(); // 请填写您的AccessKeySecret。
        String endpoint = prop.getEndpoint(); // 请填写您的 endpoint。
        //String bucket = "bucket-name"; // 请填写您的 bucketname 。
        String host = prop.getHost(); // host的格式为 bucketname.endpoint
        // callbackUrl为 上传回调服务器的URL，请将下面的IP和Port配置为您自己的真实信息。
        //String callbackUrl = "http://88.88.88.88:8888";
        String dir = ""; // 用户上传文件时指定的前缀。

        // 需要一个  OSSClient ，需要一个阿里云依赖
        // 由于以下方法已经过时，阿里提供给我们另外的方式，使用build模式 OSSconfig
        //OSSClient client = new OSSClient(endpoint, accessId, accessKey);


        try {
            // 设置签名失效时间
            long expireTime = prop.getExpireTime();
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            // 生成签名策略
            String postPolicy = client.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = client.calculatePostSignature(postPolicy);

            // 组织结果集并返回
            Map<String, Object> respMap = new LinkedHashMap<String, Object>();
            // 此处有个坑，accessId 前台要的是 id大写，阿里源码id是小写
            respMap.put("accessId", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", expireEndTime);
            // respMap.put("expire", prop.getExpireTime());
            return respMap;
            // respMap.put("expire", formatISO8601Date(expiration));

            // 以下是回调的逻辑，我们不需要，我们只需要一个签名即可
            /*JSONObject jasonCallback = new JSONObject();
            jasonCallback.put("callbackUrl", callbackUrl);
            jasonCallback.put("callbackBody",
                    "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
            jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
            String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
            respMap.put("callback", base64CallbackBody);

            JSONObject ja1 = JSONObject.fromObject(respMap);
            // System.out.println(ja1.toString());
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST");
            response(request, response, ja1.toString());*/

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            //System.out.println(e.getMessage());
            // 抛出自己的异常
            throw new LyException(ExceptionEnum.INVALID_NOTIFY_SIGN);
        }
    }
}
